﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
using System.IO;

namespace Fantasy_Fall_Level_Editor
{
    public partial class Form1 : Form
    {
        bool looping = true;
        bool grid = true;
        SGP.CSGP_Direct3D D3D = SGP.CSGP_Direct3D.GetInstance();
        SGP.CSGP_TextureManager TM = SGP.CSGP_TextureManager.GetInstance();
        LevelToolWindow levelTool = null;
        Layer_Window layerTool = null;
        Heightmap_Window heightMapTool = null;

        //int ImageID = -1;

        Bitmap tileSet = Fantasy_Fall_Level_Editor.Properties.Resources.defaultTileset;

        string tileSetFile;

        string systemPath;

        Size tileSetSize = new Size(4, 2);

        Size tileSize = new Size(64, 64);

        Tile[,] level = new Tile[4, 4];

        Size levelSize = new Size(4, 4);

        Tile selectedTile = new Tile();

        List<Layer> layers = new List<Layer>();

        List<Tile> heightMaps = new List<Tile>();

        Queue<Point> tileQueue;

        enum Mode { SELECTION_RECT_MODE, PAINTBRUSH_MODE, FILL_MODE, COPY_MODE, PASTE_MODE, HEIGHT_MAP_MODE, PLAYER_SPAWN_MODE, MELEE_GRUNT_SPAWN_MODE, MAGE_GRUNT_SPAWN_MODE, RANGED_GRUNT_SPAWN_MODE, EVENT_MODE, CHECK_POINT_MODE, HEALTH_POWERUP_MODE, SPEED_POWERUP_MODE, DAMAGE_POWERUP_MODE, CRUMBLING_PLATFORM_MODE, SWITCH_TRIGGER_MODE, WALL_TRIGGER_MODE, SPIKE_MODE, SPRINGBOARD_MODE, BOSS_MODE };

        enum Objects { NULL, PLAYER_OBJ, MELEE_GRUNT_OBJ, MAGE_GRUNT_OBJ, RANGED_GRUNT_OBJ, EVENT, CHECK_POINT_OBJ, HEALTH_POWERUP_OBJ, SPEED_POWERUP_OBJ, DAMAGE_POWERUP_OBJ, CRUMBLING_PLATFORM_OBJ, SWITCH_TRIGGER_OBJ, WALL_TRIGGER_OBJ, SPIKE_OBJ, SPRINGBOARD_OBJ, BOSS_OBJ };

        Objects[,] Spawns = new Objects[4, 4];

        Mode mode = Mode.PAINTBRUSH_MODE;

        string[,] events = new string[4, 4];

        // This is producing a waring saying it is never used. - Cliff
        //string filePath;

        public bool Looping
        {
            get { return looping; }
            set { looping = value; }
        }
        public bool Grid
        {
            get { return grid; }
            set { grid = value; }
        }
        public Form1()
        {

            InitializeComponent();

            D3D.Initialize(LevelPanel, true);
            D3D.AddRenderTarget(TileSetPanel);

            TM.Initialize(D3D.Device, D3D.Sprite);

            Size size = new Size(levelSize.Width * tileSize.Width, levelSize.Height * tileSize.Height);
            LevelPanel.AutoScrollMinSize = size;

            size = new Size(tileSetSize.Width * tileSize.Width, tileSetSize.Height * tileSize.Height);
            TileSetPanel.AutoScrollMinSize = size;

            selectedTile.HeightMap = new int[tileSize.Width];

            for (int x = 0; x < levelSize.Width; x++)
            {
                for (int y = 0; y < levelSize.Height; y++)
                {
                    level[x, y].X = x;
                    level[x, y].Y = y;
                }
            }

            for (int x = 0; x < tileSetSize.Width; x++)
            {
                for (int y = 0; y < tileSetSize.Height; y++)
                {
                    Tile temp = new Tile();
                    temp.X = x;
                    temp.Y = y;
                    temp.HeightMap = new int[tileSize.Width];

                    for (int w = 0; w < tileSize.Width; w++)
                    {
                        temp.HeightMap[w] = -1;
                        selectedTile.HeightMap[w] = -1;
                    }
                    heightMaps.Add(temp);
                }
            }

            toolStripButton8_Click(this, EventArgs.Empty);

            if (System.IO.File.Exists("leFilePath.txt"))
            {
                System.IO.StreamReader reader = new System.IO.StreamReader("leFilePath.txt");
                systemPath = reader.ReadLine();
                reader.Close();

                if (!System.IO.Directory.Exists(systemPath))
                {
                    FolderBrowserDialog dlg = new FolderBrowserDialog();
                    if (DialogResult.OK == dlg.ShowDialog())
                    {
                        systemPath = dlg.SelectedPath;
                    }
                }
            }
            else
            {
                MessageBox.Show("Pick the file path you wish to save your levels. (Only needs to be done once)");

                FolderBrowserDialog dlg = new FolderBrowserDialog();

                if (DialogResult.OK == dlg.ShowDialog())
                {
                    systemPath = dlg.SelectedPath;
                }
            }

            // ImageID = TM.LoadTexture("image.jpg"); // image location looks from bin, so don't forget relative pathing
        }

        public new void Update()
        {
        }

        public void Render()
        {
            //D3D.Clear(LevelPanel, Color.White);
            //D3D.DeviceBegin();
            //D3D.SpriteBegin();

            //D3D.DrawText("I'm a level editor", 20, 20, Color.FromArgb(255, 60, 150));
            //if (ImageID != -1)
            //TM.Draw(ImageID, 30, 30, 1.0f, 1.0f, Rectangle(ActualSize.x, ActualSize.y, ActualSize.x + width, Actualsize.y + height));

            //D3D.SpriteEnd();
            //D3D.DeviceEnd();
            //D3D.Present();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Looping = false;

            System.IO.StreamWriter writer = new System.IO.StreamWriter("leFilePath.txt");
            writer.WriteLine(systemPath);
            writer.Close();
        }

        private void importTilesetToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();

            if (DialogResult.OK == dlg.ShowDialog())
            {
                tileSet = new Bitmap(dlg.FileName);

                tileSetFile = dlg.FileName;

                Graphics g = TileSetPanel.CreateGraphics();
                tileSet.SetResolution(g.DpiX, g.DpiY);
                g.Dispose();

                LevelPanel.Invalidate();
                TileSetPanel.Invalidate();
            }
        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (levelTool != null)
                levelTool.Close();

            if (layerTool != null)
                layerTool.Close();

            toolStripButton8_Click(this, EventArgs.Empty);

            tileSet = Fantasy_Fall_Level_Editor.Properties.Resources.defaultTileset;
            tileSetSize = new Size(4, 2);
            tileSize = new Size(64, 64);
            level = new Tile[4, 4];
            levelSize = new Size(4, 4);
            Spawns = new Objects[4, 4];
            selectedTile.X = 0;
            selectedTile.Y = 0;
            layers = new List<Layer>();
            LevelPanel.Invalidate();
            TileSetPanel.Invalidate();
        }

        private void TileSetPanel_MouseClick(object sender, MouseEventArgs e)
        {
            Point offst = new Point(0, 0);

            offst.X += TileSetPanel.AutoScrollPosition.X;
            offst.Y += TileSetPanel.AutoScrollPosition.Y;

            // Calculate the tile in which the mouse click occured.
            if (e.Button == MouseButtons.Left)
            {
                for (int x = 0; x < tileSetSize.Width; ++x)
                {
                    for (int y = 0; y < tileSetSize.Height; ++y)
                    {
                        Rectangle rect = new Rectangle(offst, tileSize);
                        rect.X += tileSize.Width * x;
                        rect.Y += tileSize.Height * y;

                        if (rect.Contains(e.Location))
                        {
                            selectedTile.X = x;
                            selectedTile.Y = y;

                            for (int i = 0; i < heightMaps.Count; i++)
                            {
                                if (heightMaps[i] == selectedTile)
                                {
                                    selectedTile.HeightMap = heightMaps[i].HeightMap;
                                }
                            }

                            TileSetPanel.Invalidate();
                        }
                    }
                }

                if (mode == Mode.HEIGHT_MAP_MODE)
                {
                    for (int i = 0; i < layers.Count; i++)
                    {
                        for (int w = 0; w < levelSize.Width; w++)
                        {
                            for (int h = 0; h < levelSize.Height; h++)
                            {
                                if (selectedTile == layers[i].Level[w, h])
                                {
                                    selectedTile.HeightMap = layers[i].Level[w, h].HeightMap;
                                }
                            }
                        }
                    }

                    HeightMapWindow_Open(sender, e);
                }
            }
        }

        private void HeightMapWindow_Open(object sender, MouseEventArgs e)
        {
            if (heightMapTool == null)
            {
                if (selectedTile.X != 0 || selectedTile.Y != 0)
                {
                    heightMapTool = new Heightmap_Window();

                    if (selectedTile.HeightMap == null)
                    {
                        selectedTile.HeightMap = new int[tileSize.Width];

                        for (int i = 0; i < tileSize.Width; i++)
                        {
                            selectedTile.HeightMap[i] = -1;
                        }
                    }

                    for (int h = 0; h < heightMaps.Count; h++)
                    {
                        if (selectedTile == heightMaps[h])
                        {
                            selectedTile.HeightMap = heightMaps[h].HeightMap;
                        }
                    }

                    heightMapTool.Heightmap_Window_SelectedTile = selectedTile;

                    heightMapTool.Heightmap_Window_TileSize = tileSize;

                    heightMapTool.Heightmap_Window_TileSet = tileSet;

                    Point offst = new Point(0, 0);

                    offst.X += TileSetPanel.AutoScrollPosition.X;
                    offst.Y += TileSetPanel.AutoScrollPosition.Y;

                    heightMapTool.Heightmap_Window_Offset = offst;

                    heightMapTool.Window_Closing += HeightmapWindow_Closing;

                    heightMapTool.FormClosed += HeightMapTool_FormClosed;

                    TileSetPanel.Invalidate();

                    heightMapTool.Show(this);
                }
            }
        }


        private void HeightmapWindow_Closing(object sender, EventArgs e)
        {
            Heightmap_Window tempTool = (Heightmap_Window)sender;

            for (int i = 0; i < layers.Count; i++)
            {
                for (int x = 0; x < levelSize.Width; x++)
                {
                    for (int y = 0; y < levelSize.Height; y++)
                    {
                        for (int w = 0; w < heightMaps.Count; w++)
                        {
                            Tile temp = heightMaps[w];
                            if (temp == tempTool.Heightmap_Window_SelectedTile)
                            {
                                temp.HeightMap = tempTool.Heightmap_Window_SelectedTile.HeightMap;
                                heightMaps[w] = temp;
                                selectedTile.HeightMap = tempTool.Heightmap_Window_SelectedTile.HeightMap;
                            }

                            if (layers[i].Level[x, y] == heightMaps[w])
                            {
                                layers[i].Level[x, y].HeightMap = heightMaps[w].HeightMap;
                            }
                        }
                    }
                }
            }

            //heightMapTool = null;

        }

        private void TileSetPanel_Paint(object sender, PaintEventArgs e)
        {
            Point offst = new Point(0, 0);

            offst.X += TileSetPanel.AutoScrollPosition.X;
            offst.Y += TileSetPanel.AutoScrollPosition.Y;

            e.Graphics.DrawImage(tileSet, offst);
            Pen pen = new Pen(Color.Red, 4);
            e.Graphics.DrawRectangle(pen, selectedTile.X * tileSize.Width + offst.X, selectedTile.Y * tileSize.Height + offst.Y, tileSize.Width, tileSize.Height);

            Pen pen2 = new Pen(Color.Black, 1);
            for (int x = 0; x < tileSetSize.Width; x++)
            {
                for (int y = 0; y < tileSetSize.Height; y++)
                {
                    Rectangle rect = new Rectangle(offst, tileSize);
                    rect.X += x * tileSize.Width;
                    rect.Y += y * tileSize.Height;

                    e.Graphics.DrawRectangle(pen2, rect);
                }
            }
            pen.Dispose();
            pen2.Dispose();
        }

        private void LevelPanel_Paint(object sender, PaintEventArgs e)
        {
            ClearBackground_Paint(sender, e);

            Tiles_Paint(sender, e);

            Objects_Paint(sender, e);
        }

        // Called by LevelPanel's Paint function, just for refactoring
        private void ClearBackground_Paint(object sender, PaintEventArgs e)
        {
            Point offst = new Point(0, 0);

            offst.X += LevelPanel.AutoScrollPosition.X;
            offst.Y += LevelPanel.AutoScrollPosition.Y;

            // Iterate through all the tiles in the map.
            for (int x = 0; x < levelSize.Width; x++)
            {
                for (int y = 0; y < levelSize.Height; y++)
                {
                    // Calculate where the tile is going to be drawn in the map.
                    Rectangle destRect = new Rectangle(offst, tileSize);
                    destRect.X = x * tileSize.Width + offst.X;
                    destRect.Y = y * tileSize.Height + offst.Y;

                    // Calculate where the tile is in the bitmap.
                    Rectangle srcRect = Rectangle.Empty;
                    srcRect.X = 0;
                    srcRect.Y = 0;
                    srcRect.Size = tileSize;

                    // Draw the tile.
                    e.Graphics.DrawImage(tileSet, destRect, srcRect, GraphicsUnit.Pixel);

                    // Draw the grid.
                    if(Grid)
                        e.Graphics.DrawRectangle(Pens.Black, destRect);
                }
            }
        }

        // Called by LevelPanel's Paint function, just for refactoring
        private void Tiles_Paint(object sender, PaintEventArgs e)
        {
            for (int i = 0; i < layers.Count; ++i)
            {
                if (layers[i].Visible)
                {
                    Point offset = new Point(0, 0);

                    offset.X += LevelPanel.AutoScrollPosition.X;
                    offset.Y += LevelPanel.AutoScrollPosition.Y;

                    // Iterate through all the tiles in the map.
                    for (int x = 0; x < levelSize.Width; x++)
                    {
                        for (int y = 0; y < levelSize.Height; y++)
                        {
                            // Calculate where the tile is going to be drawn in the map.
                            Rectangle destRect = Rectangle.Empty;
                            destRect.X = x * tileSize.Width + offset.X;
                            destRect.Y = y * tileSize.Height + offset.Y;
                            destRect.Size = tileSize;

                            // Calculate where the tile is in the bitmap.
                            Rectangle srcRect = Rectangle.Empty;
                            srcRect.X = layers[i].Level[x, y].X * tileSize.Width;
                            srcRect.Y = layers[i].Level[x, y].Y * tileSize.Height;
                            srcRect.Size = tileSize;

                            if (layers[i].Level[x, y].X * tileSize.Width != 0 || layers[i].Level[x, y].Y * tileSize.Height != 0)
                            {
                                // Draw the tile.
                                e.Graphics.DrawImage(tileSet, destRect, srcRect, GraphicsUnit.Pixel);
                            }

                            // Draw the grid.
                            if(Grid)
                                e.Graphics.DrawRectangle(Pens.Black, destRect);
                        }
                    }
                }
            }
        }

        // Called by LevelPanel's Paint function, just for refactoring
        private void Objects_Paint(object sender, PaintEventArgs e)
        {
            Point offset = new Point(0, 0);

            offset.X += LevelPanel.AutoScrollPosition.X;
            offset.Y += LevelPanel.AutoScrollPosition.Y;

            // Iterate through all the tiles in the map.
            for (int x = 0; x < levelSize.Width; x++)
            {
                for (int y = 0; y < levelSize.Height; y++)
                {
                    // Calculate where the object is going to be drawn in the map.
                    Rectangle destRect = Rectangle.Empty;
                    destRect.X = x * tileSize.Width + offset.X;
                    destRect.Y = y * tileSize.Height + offset.Y;
                    destRect.Size = new Size(tileSize.Width / 4, tileSize.Height / 4);

                    if (Spawns[x, y] == Objects.PLAYER_OBJ)
                    {
                        // Draw the tile.
                        e.Graphics.DrawImage(Player_Spawn_Button.Image, destRect);
                    }

                    else if (Spawns[x, y] == Objects.MAGE_GRUNT_OBJ)
                    {
                        e.Graphics.DrawImage(Mage_Grunt_Spawn_Button.Image, destRect);
                    }

                    else if (Spawns[x, y] == Objects.RANGED_GRUNT_OBJ)
                    {
                        e.Graphics.DrawImage(Ranger_Grunt_Spawn_Button.Image, destRect);
                    }

                    else if (Spawns[x, y] == Objects.MELEE_GRUNT_OBJ)
                    {
                        e.Graphics.DrawImage(Melee_Grunt_Spawn_Button.Image, destRect);
                    }

                    else if (Spawns[x, y] == Objects.EVENT)
                    {
                        e.Graphics.DrawImage(Event_Button.Image, destRect);
                    }

                    else if (Spawns[x, y] == Objects.CHECK_POINT_OBJ)
                    {
                        e.Graphics.DrawImage(Check_Point_Button.Image, destRect);
                    }

                    else if (Spawns[x, y] == Objects.HEALTH_POWERUP_OBJ)
                    {
                        e.Graphics.DrawImage(Health_Powerup_Button.Image, destRect);
                    }

                    else if (Spawns[x, y] == Objects.SPEED_POWERUP_OBJ)
                    {
                        e.Graphics.DrawImage(Speed_Powerup_Button.Image, destRect);
                    }

                    else if (Spawns[x, y] == Objects.DAMAGE_POWERUP_OBJ)
                    {
                        e.Graphics.DrawImage(Damage_Powerup_Button.Image, destRect);
                    }

                    else if (Spawns[x, y] == Objects.CRUMBLING_PLATFORM_OBJ)
                    {
                        e.Graphics.DrawImage(Crumbling_Platform_Button.Image, destRect);
                    }
                    else if (Spawns[x, y] == Objects.WALL_TRIGGER_OBJ)
                    {
                        e.Graphics.DrawImage(Wall_Trigger_Button.Image, destRect);
                    }
                    else if (Spawns[x, y] == Objects.SWITCH_TRIGGER_OBJ)
                    {
                        e.Graphics.DrawImage(Switch_Trigger_Button.Image, destRect);
                    }
                    else if (Spawns[x, y] == Objects.SPIKE_OBJ)
                    {
                        e.Graphics.DrawImage(Spike_Button.Image, destRect);
                    }
                    else if (Spawns[x, y] == Objects.SPRINGBOARD_OBJ)
                    {
                        e.Graphics.DrawImage(Springboard_Button.Image, destRect);
                    }
                    else if(Spawns[x, y] == Objects.BOSS_OBJ)
                    {
                        e.Graphics.DrawImage(Boss_Button.Image, destRect);
                    }
                }
            }
        }

        private void LevelPanel_MouseClick(object sender, MouseEventArgs e)
        {
            if (layers.Count < 1)
            {
                MessageBox.Show("You need to make a layer before you can draw", "Critical Warning",
                                MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            if (mode == Mode.PAINTBRUSH_MODE)
            {
                PaintBrush_Click(sender, e);
            }

            else if (mode == Mode.FILL_MODE)
            {
                Fill_Click(sender, e);
            }

            else if (mode == Mode.PLAYER_SPAWN_MODE)
            {
                Player_Spawn_Mode_Click(sender, e);
            }

            else if (mode == Mode.MELEE_GRUNT_SPAWN_MODE)
            {
                Melee_Grunt_Spawn_Mode_Click(sender, e);
            }

            else if (mode == Mode.MAGE_GRUNT_SPAWN_MODE)
            {
                Mage_Grunt_Spawn_Mode_Click(sender, e);
            }

            else if (mode == Mode.RANGED_GRUNT_SPAWN_MODE)
            {
                Ranger_Grunt_Spawn_Mode_Click(sender, e);
            }

            else if (mode == Mode.EVENT_MODE)
            {
                Event_Mode_Click(sender, e);
            }

            else if (mode == Mode.CHECK_POINT_MODE)
            {
                Check_Point_Mode_Click(sender, e);
            }

            else if (mode == Mode.HEALTH_POWERUP_MODE)
            {
                Health_Powerup_Mode_Click(sender, e);
            }

            else if (mode == Mode.SPEED_POWERUP_MODE)
            {
                Speed_Powerup_Mode_Click(sender, e);
            }

            else if (mode == Mode.DAMAGE_POWERUP_MODE)
            {
                Damage_Powerup_Mode_Click(sender, e);
            }

            else if (mode == Mode.CRUMBLING_PLATFORM_MODE)
            {
                Crumbling_Platform_Mode_Click(sender, e);
            }
            else if (mode == Mode.SWITCH_TRIGGER_MODE)
            {
                Switch_Trigger_Mode_Click(sender, e);
            }
            else if (mode == Mode.WALL_TRIGGER_MODE)
            {
                Wall_Trigger_Mode_Click(sender, e);
            }
            else if (mode == Mode.SPIKE_MODE)
            {
                Spike_Mode_Click(sender, e);
            }
            else if (mode == Mode.SPRINGBOARD_MODE)
            {
                Springboard_Mode_Click(sender, e);
            }
            else if (mode == Mode.BOSS_MODE)
            {
                Boss_Mode_Click(sender, e);
            }

            LevelPanel.Invalidate();
        }

        // Called by LevelPanel's MouseClick function, just for refactoring
        private void PaintBrush_Click(object sender, MouseEventArgs e)
        {
            Point offset = new Point(0, 0);

            offset.X += LevelPanel.AutoScrollPosition.X;
            offset.Y += LevelPanel.AutoScrollPosition.Y;

            Rectangle rect;

            for (int x = 0; x < levelSize.Width; ++x)
            {
                for (int y = 0; y < levelSize.Height; ++y)
                {
                    rect = new Rectangle(offset, tileSize);
                    rect.X += tileSize.Width * x;
                    rect.Y += tileSize.Height * y;

                    if (rect.Contains(e.Location))
                    {
                        if (layerTool.SelectedLayerIndex > -1)
                        {
                            Layer l = layers[layerTool.SelectedLayerIndex];
                            l.Level[x, y] = selectedTile;
                            layers[layerTool.SelectedLayerIndex] = l;
                        }
                    }
                }
            }
        }

        // Called by LevelPanel's MouseClick function, just for refactoring
        private void Fill_Click(object sender, MouseEventArgs e)
        {
            Point offset = new Point(0, 0);

            offset.X += LevelPanel.AutoScrollPosition.X;
            offset.Y += LevelPanel.AutoScrollPosition.Y;

            Rectangle rect;

            Tile fillTile = new Tile();
            int originX = 0;
            int originY = 0;

            for (int x = 0; x < levelSize.Width; ++x)
            {
                for (int y = 0; y < levelSize.Height; ++y)
                {
                    rect = new Rectangle(offset, tileSize);
                    rect.X += tileSize.Width * x;
                    rect.Y += tileSize.Height * y;

                    if (rect.Contains(e.Location))
                    {
                        if (layerTool.SelectedLayerIndex > -1)
                        {
                            Layer l = layers[layerTool.SelectedLayerIndex];
                            fillTile = l.Level[x, y];
                            originX = rect.X - offset.X;
                            originY = rect.Y - offset.Y;
                        }
                    }
                }
            }

            tileQueue = new Queue<Point>();
            tileQueue.Enqueue(new Point(originX / tileSize.Width, originY / tileSize.Height));

            while (tileQueue.Any())
            {
                Point point = tileQueue.Dequeue();

                Layer l = layers[layerTool.SelectedLayerIndex];

                if (l.Level[point.X, point.Y] != fillTile)
                {
                    continue;
                }

                l.Level[point.X, point.Y] = selectedTile;

                AddtoQueueIfMatches(l.Level, tileQueue, point.X - 1, point.Y, fillTile);
                AddtoQueueIfMatches(l.Level, tileQueue, point.X + 1, point.Y, fillTile);
                AddtoQueueIfMatches(l.Level, tileQueue, point.X, point.Y - 1, fillTile);
                AddtoQueueIfMatches(l.Level, tileQueue, point.X, point.Y + 1, fillTile);
            }
        }

        // Called by the Fill Click function, makes Fill Click easier to read
        private void AddtoQueueIfMatches(Tile[,] level, Queue<Point> tileQueue, int x, int y, Tile fillTile)
        {
            if (x < 0 || x >= levelSize.Width || y < 0 || y >= levelSize.Height)
                return;

            if (level[x, y] == fillTile)
                tileQueue.Enqueue(new Point(x, y));
        }

        // Called by LevelPanel's MouseClick function, just for refactoring
        private void Player_Spawn_Mode_Click(object sender, MouseEventArgs e)
        {
            for (int x = 0; x < levelSize.Width; x++)
            {
                for (int y = 0; y < levelSize.Height; y++)
                {
                    if (Spawns[x, y] == Objects.PLAYER_OBJ)
                    {
                        Spawns[x, y] = Objects.NULL;
                    }
                }
            }

            Point offset = new Point(0, 0);

            offset.X += LevelPanel.AutoScrollPosition.X;
            offset.Y += LevelPanel.AutoScrollPosition.Y;

            Rectangle rect;

            for (int x = 0; x < levelSize.Width; ++x)
            {
                for (int y = 0; y < levelSize.Height; ++y)
                {
                    rect = new Rectangle(offset, tileSize);
                    rect.X += tileSize.Width * x;
                    rect.Y += tileSize.Height * y;

                    if (rect.Contains(e.Location))
                    {
                        if (Spawns[x, y] != Objects.PLAYER_OBJ)
                        {
                            Spawns[x, y] = Objects.PLAYER_OBJ;
                        }
                        else
                        {
                            Spawns[x, y] = 0;
                        }
                    }
                }
            }
        }

        // Called by LevelPanel's MouseClick function, just for refactoring
        private void Melee_Grunt_Spawn_Mode_Click(object sender, MouseEventArgs e)
        {
            Point offset = new Point(0, 0);

            offset.X += LevelPanel.AutoScrollPosition.X;
            offset.Y += LevelPanel.AutoScrollPosition.Y;

            Rectangle rect;

            for (int x = 0; x < levelSize.Width; ++x)
            {
                for (int y = 0; y < levelSize.Height; ++y)
                {
                    rect = new Rectangle(offset, tileSize);
                    rect.X += tileSize.Width * x;
                    rect.Y += tileSize.Height * y;

                    if (rect.Contains(e.Location))
                    {
                        if (Spawns[x, y] != Objects.MELEE_GRUNT_OBJ)
                        {
                            Spawns[x, y] = Objects.MELEE_GRUNT_OBJ;
                        }
                        else
                        {
                            Spawns[x, y] = 0;
                        }
                    }
                }
            }
        }

        // Called by LevelPanel's MouseClick function, just for refactoring
        private void Mage_Grunt_Spawn_Mode_Click(object sender, MouseEventArgs e)
        {
            Point offset = new Point(0, 0);

            offset.X += LevelPanel.AutoScrollPosition.X;
            offset.Y += LevelPanel.AutoScrollPosition.Y;

            Rectangle rect;

            for (int x = 0; x < levelSize.Width; ++x)
            {
                for (int y = 0; y < levelSize.Height; ++y)
                {
                    rect = new Rectangle(offset, tileSize);
                    rect.X += tileSize.Width * x;
                    rect.Y += tileSize.Height * y;

                    if (rect.Contains(e.Location))
                    {
                        if (Spawns[x, y] != Objects.MAGE_GRUNT_OBJ)
                        {
                            Spawns[x, y] = Objects.MAGE_GRUNT_OBJ;
                        }
                        else
                        {
                            Spawns[x, y] = 0;
                        }
                    }
                }
            }
        }

        // Called by LevelPanel's MouseClick function, just for refactoring
        private void Ranger_Grunt_Spawn_Mode_Click(object sender, MouseEventArgs e)
        {
            Point offset = new Point(0, 0);

            offset.X += LevelPanel.AutoScrollPosition.X;
            offset.Y += LevelPanel.AutoScrollPosition.Y;

            Rectangle rect;

            for (int x = 0; x < levelSize.Width; ++x)
            {
                for (int y = 0; y < levelSize.Height; ++y)
                {
                    rect = new Rectangle(offset, tileSize);
                    rect.X += tileSize.Width * x;
                    rect.Y += tileSize.Height * y;

                    if (rect.Contains(e.Location))
                    {
                        if (Spawns[x, y] != Objects.RANGED_GRUNT_OBJ)
                        {
                            Spawns[x, y] = Objects.RANGED_GRUNT_OBJ;
                        }
                        else
                        {
                            Spawns[x, y] = 0;
                        }
                    }
                }
            }
        }

        // Called by LevelPanel's MouseClick function, just for refactoring
        private void Event_Mode_Click(object sender, MouseEventArgs e)
        {
            Point offset = new Point(0, 0);

            offset.X += LevelPanel.AutoScrollPosition.X;
            offset.Y += LevelPanel.AutoScrollPosition.Y;

            Rectangle rect;

            for (int x = 0; x < levelSize.Width; ++x)
            {
                for (int y = 0; y < levelSize.Height; ++y)
                {
                    rect = new Rectangle(offset, tileSize);
                    rect.X += tileSize.Width * x;
                    rect.Y += tileSize.Height * y;

                    if (rect.Contains(e.Location))
                    {
                        if (Spawns[x, y] != Objects.EVENT)
                        {
                            Spawns[x, y] = Objects.EVENT;
                            events[x, y] = Event_ComboBox.Text;
                        }
                        else
                        {
                            Spawns[x, y] = 0;
                        }
                    }
                }
            }
        }

        // Called by LevelPanel's MouseClick function, just for refactoring
        private void Crumbling_Platform_Mode_Click(object sender, MouseEventArgs e)
        {
            Point offset = new Point(0, 0);

            offset.X += LevelPanel.AutoScrollPosition.X;
            offset.Y += LevelPanel.AutoScrollPosition.Y;

            Rectangle rect;

            for (int x = 0; x < levelSize.Width; ++x)
            {
                for (int y = 0; y < levelSize.Height; ++y)
                {
                    rect = new Rectangle(offset, tileSize);
                    rect.X += tileSize.Width * x;
                    rect.Y += tileSize.Height * y;

                    if (rect.Contains(e.Location))
                    {
                        if (Spawns[x, y] != Objects.CRUMBLING_PLATFORM_OBJ)
                        {
                            Spawns[x, y] = Objects.CRUMBLING_PLATFORM_OBJ;
                        }
                        else
                        {
                            Spawns[x, y] = 0;
                        }
                    }
                }
            }
        }
        // Called by LevelPanel's MouseClick function, just for refactoring
        private void Check_Point_Mode_Click(object sender, MouseEventArgs e)
        {
            Point offset = new Point(0, 0);

            offset.X += LevelPanel.AutoScrollPosition.X;
            offset.Y += LevelPanel.AutoScrollPosition.Y;

            Rectangle rect;

            for (int x = 0; x < levelSize.Width; ++x)
            {
                for (int y = 0; y < levelSize.Height; ++y)
                {
                    rect = new Rectangle(offset, tileSize);
                    rect.X += tileSize.Width * x;
                    rect.Y += tileSize.Height * y;

                    if (rect.Contains(e.Location))
                    {
                        if (Spawns[x, y] != Objects.CHECK_POINT_OBJ)
                        {
                            Spawns[x, y] = Objects.CHECK_POINT_OBJ;
                        }
                        else
                        {
                            Spawns[x, y] = 0;
                        }
                    }
                }
            }
        }

        private void Health_Powerup_Mode_Click(object sender, MouseEventArgs e)
        {
            Point offset = new Point(0, 0);

            offset.X += LevelPanel.AutoScrollPosition.X;
            offset.Y += LevelPanel.AutoScrollPosition.Y;

            Rectangle rect;

            for (int x = 0; x < levelSize.Width; ++x)
            {
                for (int y = 0; y < levelSize.Height; ++y)
                {
                    rect = new Rectangle(offset, tileSize);
                    rect.X += tileSize.Width * x;
                    rect.Y += tileSize.Height * y;

                    if (rect.Contains(e.Location))
                    {
                        if (Spawns[x, y] != Objects.HEALTH_POWERUP_OBJ)
                        {
                            Spawns[x, y] = Objects.HEALTH_POWERUP_OBJ;
                        }
                        else
                        {
                            Spawns[x, y] = 0;
                        }
                    }
                }
            }
        }

        private void Speed_Powerup_Mode_Click(object sender, MouseEventArgs e)
        {
            Point offset = new Point(0, 0);

            offset.X += LevelPanel.AutoScrollPosition.X;
            offset.Y += LevelPanel.AutoScrollPosition.Y;

            Rectangle rect;

            for (int x = 0; x < levelSize.Width; ++x)
            {
                for (int y = 0; y < levelSize.Height; ++y)
                {
                    rect = new Rectangle(offset, tileSize);
                    rect.X += tileSize.Width * x;
                    rect.Y += tileSize.Height * y;

                    if (rect.Contains(e.Location))
                    {
                        if (Spawns[x, y] != Objects.SPEED_POWERUP_OBJ)
                        {
                            Spawns[x, y] = Objects.SPEED_POWERUP_OBJ;
                        }
                        else
                        {
                            Spawns[x, y] = 0;
                        }
                    }
                }
            }
        }

        private void Damage_Powerup_Mode_Click(object sender, MouseEventArgs e)
        {
            Point offset = new Point(0, 0);

            offset.X += LevelPanel.AutoScrollPosition.X;
            offset.Y += LevelPanel.AutoScrollPosition.Y;

            Rectangle rect;

            for (int x = 0; x < levelSize.Width; ++x)
            {
                for (int y = 0; y < levelSize.Height; ++y)
                {
                    rect = new Rectangle(offset, tileSize);
                    rect.X += tileSize.Width * x;
                    rect.Y += tileSize.Height * y;

                    if (rect.Contains(e.Location))
                    {
                        if (Spawns[x, y] != Objects.DAMAGE_POWERUP_OBJ)
                        {
                            Spawns[x, y] = Objects.DAMAGE_POWERUP_OBJ;
                        }
                        else
                        {
                            Spawns[x, y] = 0;
                        }
                    }
                }
            }
        }
        private void Switch_Trigger_Mode_Click(object sender, MouseEventArgs e)
        {
            Point offset = new Point(0, 0);

            offset.X += LevelPanel.AutoScrollPosition.X;
            offset.Y += LevelPanel.AutoScrollPosition.Y;

            Rectangle rect;

            for (int x = 0; x < levelSize.Width; ++x)
            {
                for (int y = 0; y < levelSize.Height; ++y)
                {
                    rect = new Rectangle(offset, tileSize);
                    rect.X += tileSize.Width * x;
                    rect.Y += tileSize.Height * y;

                    if (rect.Contains(e.Location))
                    {
                        if (Spawns[x, y] != Objects.SWITCH_TRIGGER_OBJ)
                        {
                            Spawns[x, y] = Objects.SWITCH_TRIGGER_OBJ;
                        }
                        else
                        {
                            Spawns[x, y] = 0;
                        }
                    }
                }
            }
        }
        private void Wall_Trigger_Mode_Click(object sender, MouseEventArgs e)
        {
            Point offset = new Point(0, 0);

            offset.X += LevelPanel.AutoScrollPosition.X;
            offset.Y += LevelPanel.AutoScrollPosition.Y;

            Rectangle rect;

            for (int x = 0; x < levelSize.Width; ++x)
            {
                for (int y = 0; y < levelSize.Height; ++y)
                {
                    rect = new Rectangle(offset, tileSize);
                    rect.X += tileSize.Width * x;
                    rect.Y += tileSize.Height * y;

                    if (rect.Contains(e.Location))
                    {
                        if (Spawns[x, y] != Objects.WALL_TRIGGER_OBJ)
                        {
                            Spawns[x, y] = Objects.WALL_TRIGGER_OBJ;
                        }
                        else
                        {
                            Spawns[x, y] = 0;
                        }
                    }
                }
            }
        }

        private void Spike_Mode_Click(object sender, MouseEventArgs e)
        {
            Point offset = new Point(0, 0);

            offset.X += LevelPanel.AutoScrollPosition.X;
            offset.Y += LevelPanel.AutoScrollPosition.Y;

            Rectangle rect;

            for (int x = 0; x < levelSize.Width; ++x)
            {
                for (int y = 0; y < levelSize.Height; ++y)
                {
                    rect = new Rectangle(offset, tileSize);
                    rect.X += tileSize.Width * x;
                    rect.Y += tileSize.Height * y;

                    if (rect.Contains(e.Location))
                    {
                        if (Spawns[x, y] != Objects.SPIKE_OBJ)
                        {
                            Spawns[x, y] = Objects.SPIKE_OBJ;
                        }
                        else
                        {
                            Spawns[x, y] = 0;
                        }
                    }
                }
            }
        }

        private void Springboard_Mode_Click(object sender, MouseEventArgs e)
        {
            Point offset = new Point(0, 0);

            offset.X += LevelPanel.AutoScrollPosition.X;
            offset.Y += LevelPanel.AutoScrollPosition.Y;

            Rectangle rect;

            for (int x = 0; x < levelSize.Width; ++x)
            {
                for (int y = 0; y < levelSize.Height; ++y)
                {
                    rect = new Rectangle(offset, tileSize);
                    rect.X += tileSize.Width * x;
                    rect.Y += tileSize.Height * y;

                    if (rect.Contains(e.Location))
                    {
                        if (Spawns[x, y] != Objects.SPRINGBOARD_OBJ)
                        {
                            Spawns[x, y] = Objects.SPRINGBOARD_OBJ;
                        }
                        else
                        {
                            Spawns[x, y] = 0;
                        }
                    }
                }
            }
        }

        private void Boss_Mode_Click(object sender, MouseEventArgs e)
        {
            Point offset = new Point(0, 0);

            offset.X += LevelPanel.AutoScrollPosition.X;
            offset.Y += LevelPanel.AutoScrollPosition.Y;

            Rectangle rect;

            for (int x = 0; x < levelSize.Width; ++x)
            {
                for (int y = 0; y < levelSize.Height; ++y)
                {
                    rect = new Rectangle(offset, tileSize);
                    rect.X += tileSize.Width * x;
                    rect.Y += tileSize.Height * y;

                    if (rect.Contains(e.Location))
                    {
                        if (Spawns[x, y] != Objects.BOSS_OBJ)
                        {
                            Spawns[x, y] = Objects.BOSS_OBJ;
                        }
                        else
                        {
                            Spawns[x, y] = 0;
                        }
                    }
                }
            }
        }

        private void LevelPanel_MouseMove(object sender, MouseEventArgs e)
        {
            if (mode == Mode.PAINTBRUSH_MODE)
            {
                Rectangle rect = new Rectangle(0, 0, LevelPanel.Width, LevelPanel.Height);
                if (e.Button == MouseButtons.Left && rect.Contains(e.Location))
                {
                    LevelPanel_MouseClick(sender, e);
                }
            }
        }

        private void LevelTool_FormClosed(object sender, FormClosedEventArgs e)
        {
            levelTool = null;
        }

        private void LayerTool_FormClosed(object sender, FormClosedEventArgs e)
        {
            layerTool = null;
        }

        private void HeightMapTool_FormClosed(object sender, FormClosedEventArgs e)
        {
            heightMapTool = null;
        }

        private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (levelTool == null)
            {
                levelTool = new LevelToolWindow();
                levelTool.LevelToolWindow_NumericUpDown1_Value = levelSize.Width;
                levelTool.LevelToolWindow_NumericUpDown2_Value = levelSize.Height;
                levelTool.LevelToolWindow_NumericUpDown3_Value = tileSetSize.Width;
                levelTool.LevelToolWindow_NumericUpDown4_Value = tileSetSize.Height;
                levelTool.LevelToolWindow_NumericUpDown5_Value = tileSize.Width;
                levelTool.LevelToolWindow_NumericUpDown6_Value = tileSize.Height;

                levelTool.FormClosed += LevelTool_FormClosed;

                levelTool.Button1LevelUpdate += LevelTool_Button1LevelUpdate;

                levelTool.NumUpDown3Change += LevelTool_NumUpDown3Change;

                levelTool.NumUpDown4Change += LevelTool_NumUpDown4Change;

                levelTool.NumUpDown5Change += LevelTool_NumUpDown5Change;

                levelTool.NumUpDown6Change += LevelTool_NumUpDown6Change;

                levelTool.Show(this);
            }
        }

        // Actually changes information about the level and associated info set in the level tool
        private void LevelTool_Button1LevelUpdate(object sender, EventArgs e)
        {
            LevelToolWindow tempTool = (LevelToolWindow)sender;
            Size tempMapSize = levelSize;
            level = new Tile[(int)tempTool.LevelToolWindow_NumericUpDown1_Value, (int)tempTool.LevelToolWindow_NumericUpDown2_Value];
            levelSize = new Size((int)tempTool.LevelToolWindow_NumericUpDown1_Value, (int)tempTool.LevelToolWindow_NumericUpDown2_Value);
            Spawns = new Objects[(int)tempTool.LevelToolWindow_NumericUpDown1_Value, (int)tempTool.LevelToolWindow_NumericUpDown2_Value];
            events = new string[(int)tempTool.LevelToolWindow_NumericUpDown1_Value, (int)tempTool.LevelToolWindow_NumericUpDown2_Value];

            if (tempMapSize.Width > levelSize.Width)
                tempMapSize.Width = levelSize.Width;

            if (tempMapSize.Height > levelSize.Height)
                tempMapSize.Height = levelSize.Height;

            for (int k = 0; k < layers.Count(); k++)
            {
                Tile[,] tempLevel = layers[k].Level;

                layers[k].Level = null;
                layers[k].Level = new Tile[levelSize.Width, levelSize.Height];
                for (int i = 0; i < tempMapSize.Width; i++)
                {
                    for (int j = 0; j < tempMapSize.Height; j++)
                    {
                        layers[k].Level[i, j] = tempLevel[i, j];
                    }
                }
            }

            Size size = new Size(levelSize.Width * tileSize.Width, levelSize.Height * tileSize.Height);
            LevelPanel.AutoScrollMinSize = size;

            LevelPanel.Invalidate();
        }

        // Event for Level Tool to actively change info as info is changed
        private void LevelTool_NumUpDown3Change(object sender, EventArgs e)
        {
            LevelToolWindow tempTool = (LevelToolWindow)sender;

            tileSetSize.Width = (int)tempTool.LevelToolWindow_NumericUpDown3_Value;

            Size size = new Size(tileSetSize.Width * tileSize.Width, tileSetSize.Height * tileSize.Height);
            TileSetPanel.AutoScrollMinSize = size;

            List<Tile> newHeightMaps = new List<Tile>();

            for (int x = 0; x < tileSetSize.Width; x++)
            {
                for (int y = 0; y < tileSetSize.Height; y++)
                {
                    Tile temp = new Tile();
                    temp.X = x;
                    temp.Y = y;
                    temp.HeightMap = new int[tileSize.Width];

                    for (int w = 0; w < tileSize.Width; w++)
                    {
                        temp.HeightMap[w] = -1;
                        selectedTile.HeightMap[w] = -1;
                    }
                    newHeightMaps.Add(temp);
                }
            }
            for (int i = 0; i < heightMaps.Count; i++)
            {
                if (heightMaps.Count < newHeightMaps.Count)
                {
                    newHeightMaps[i] = heightMaps[i];
                }
            }

            heightMaps = newHeightMaps;

            TileSetPanel.Invalidate();
            LevelPanel.Invalidate();
        }

        // Event for Level Tool to actively change info as info is changed
        private void LevelTool_NumUpDown4Change(object sender, EventArgs e)
        {
            LevelToolWindow tempTool = (LevelToolWindow)sender;

            tileSetSize.Height = (int)tempTool.LevelToolWindow_NumericUpDown4_Value;

            Size size = new Size(tileSetSize.Width * tileSize.Width, tileSetSize.Height * tileSize.Height);
            TileSetPanel.AutoScrollMinSize = size;

            List<Tile> newHeightMaps = new List<Tile>();

            for (int x = 0; x < tileSetSize.Width; x++)
            {
                for (int y = 0; y < tileSetSize.Height; y++)
                {
                    Tile temp = new Tile();
                    temp.X = x;
                    temp.Y = y;
                    temp.HeightMap = new int[tileSize.Width];

                    for (int w = 0; w < tileSize.Width; w++)
                    {
                        temp.HeightMap[w] = -1;
                        selectedTile.HeightMap[w] = -1;
                    }
                    newHeightMaps.Add(temp);
                }
            }

            for (int i = 0; i < heightMaps.Count; i++)
            {
                if (heightMaps.Count < newHeightMaps.Count)
                {
                    newHeightMaps[i] = heightMaps[i];
                }
            }

            heightMaps = newHeightMaps;

            TileSetPanel.Invalidate();
            LevelPanel.Invalidate();
        }

        // Event for Level Tool to actively change info as info is changed
        private void LevelTool_NumUpDown5Change(object sender, EventArgs e)
        {
            LevelToolWindow tempTool = (LevelToolWindow)sender;

            tileSize.Width = (int)tempTool.LevelToolWindow_NumericUpDown5_Value;

            Size size = new Size(tileSetSize.Width * tileSize.Width, tileSetSize.Height * tileSize.Height);
            TileSetPanel.AutoScrollMinSize = size;

            List<Tile> newHeightMaps = new List<Tile>();

            for (int x = 0; x < tileSetSize.Width; x++)
            {
                for (int y = 0; y < tileSetSize.Height; y++)
                {
                    Tile temp = new Tile();
                    temp.X = x;
                    temp.Y = y;
                    temp.HeightMap = new int[tileSize.Width];

                    for (int w = 0; w < tileSize.Width; w++)
                    {
                        temp.HeightMap[w] = -1;
                        selectedTile.HeightMap[w] = -1;
                    }
                    newHeightMaps.Add(temp);
                }
            }

            for (int i = 0; i < heightMaps.Count; i++)
            {
                if (heightMaps.Count < newHeightMaps.Count)
                {
                    newHeightMaps[i] = heightMaps[i];
                }
            }

            heightMaps = newHeightMaps;

            TileSetPanel.Invalidate();
            LevelPanel.Invalidate();
        }

        // Event for Level Tool to actively change info as info is changed
        private void LevelTool_NumUpDown6Change(object sender, EventArgs e)
        {
            LevelToolWindow tempTool = (LevelToolWindow)sender;

            tileSize.Height = (int)tempTool.LevelToolWindow_NumericUpDown6_Value;

            Size size = new Size(tileSetSize.Width * tileSize.Width, tileSetSize.Height * tileSize.Height);
            TileSetPanel.AutoScrollMinSize = size;

            List<Tile> newHeightMaps = new List<Tile>();

            for (int x = 0; x < tileSetSize.Width; x++)
            {
                for (int y = 0; y < tileSetSize.Height; y++)
                {
                    Tile temp = new Tile();
                    temp.X = x;
                    temp.Y = y;
                    temp.HeightMap = new int[tileSize.Width];

                    for (int w = 0; w < tileSize.Width; w++)
                    {
                        temp.HeightMap[w] = -1;
                        selectedTile.HeightMap[w] = -1;
                    }
                    newHeightMaps.Add(temp);
                }
            }

            for (int i = 0; i < heightMaps.Count; i++)
            {
                if (heightMaps.Count < newHeightMaps.Count)
                {
                    newHeightMaps[i] = heightMaps[i];
                }
            }

            heightMaps = newHeightMaps;

            TileSetPanel.Invalidate();
            LevelPanel.Invalidate();
        }

        private void toolStripButton8_Click(object sender, EventArgs e)
        {
            if (layerTool == null)
            {
                layerTool = new Layer_Window();

                layerTool.FormClosed += LayerTool_FormClosed;

                layerTool.Layers = layers;

                layerTool.ListBoxChange += LayerTool_ListBoxChange;

                layerTool.VisibleChange += LayerTool_VisibleChange;

                layerTool.LayerAdded += Layer_Added;

                layerTool.Show(this);
            }
        }

        private void LayerTool_ListBoxChange(object sender, EventArgs e)
        {
            Layer_Window tempTool = (Layer_Window)sender;

            layers = tempTool.Layers;

            LevelPanel.Invalidate();
        }

        private void LayerTool_VisibleChange(object sender, EventArgs e)
        {
            LevelPanel.Invalidate();
        }

        private void Layer_Added(object sender, EventArgs e)
        {
            for (int i = 0; i < layerTool.Layers.Count; i++)
            {
                Layer l = new Layer();
                l.Level = new Tile[levelSize.Width, levelSize.Height];

                for (int x = 0; x < layerTool.Layers[i].Level.GetLowerBound(0); x++)
                {
                    for (int y = 0; y < layerTool.Layers[i].Level.GetLowerBound(1); y++)
                    {
                        l.Level[x, y] = layerTool.Layers[i].Level[x, y];
                    }
                }

                layerTool.Layers[i].Level = l.Level;
            }

            for (int i = 0; i < layers.Count; i++)
            {
                for (int x = 0; x < levelSize.Width; x++)
                {
                    for (int y = 0; y < levelSize.Height; y++)
                    {
                        if (layers[i].Level[x, y].HeightMap == null)
                        {
                            layers[i].Level[x, y].HeightMap = new int[tileSize.Width];
                        }
                    }
                }
            }

            Objects[,] o = new Objects[levelSize.Width, levelSize.Height];
            string[,] s = new string[levelSize.Width, levelSize.Height];

            for (int x = 0; x < Spawns.GetLowerBound(0); x++)
            {
                for (int y = 0; y < Spawns.GetLowerBound(1); y++)
                {
                    o[x, y] = Spawns[x, y];
                    s[x, y] = events[x, y];
                }
            }
            Spawns = o;
            events = s;

            layers = layerTool.Layers;
            LevelPanel.Invalidate();
        }

        public List<Layer> Form_Layers
        {
            get { return layers; }
            set { layers = value; }
        }


        private void Fill_Button_Click(object sender, EventArgs e)
        {
            mode = Mode.FILL_MODE;

            Fill_Button.Checked = true;

            Wall_Trigger_Button.Checked = false;
            Switch_Trigger_Button.Checked = false;
            Check_Point_Button.Checked = false;
            Damage_Powerup_Button.Checked = false;
            Speed_Powerup_Button.Checked = false;
            Health_Powerup_Button.Checked = false;
            Crumbling_Platform_Button.Checked = false;
            Paint_Brush_Button.Checked = false;
            Height_Map_Button.Checked = false;
            Player_Spawn_Button.Checked = false;
            Melee_Grunt_Spawn_Button.Checked = false;
            Mage_Grunt_Spawn_Button.Checked = false;
            Ranger_Grunt_Spawn_Button.Checked = false;
            Event_Button.Checked = false;
            Spike_Button.Checked = false;
            Springboard_Button.Checked = false;
            Boss_Button.Checked = false;
        }

        private void Paint_Brush_Button_Click(object sender, EventArgs e)
        {
            mode = Mode.PAINTBRUSH_MODE;

            Paint_Brush_Button.Checked = true;

            Wall_Trigger_Button.Checked = false;
            Switch_Trigger_Button.Checked = false;
            Check_Point_Button.Checked = false;
            Damage_Powerup_Button.Checked = false;
            Speed_Powerup_Button.Checked = false;
            Health_Powerup_Button.Checked = false;
            Crumbling_Platform_Button.Checked = false;
            Fill_Button.Checked = false;
            Height_Map_Button.Checked = false;
            Player_Spawn_Button.Checked = false;
            Melee_Grunt_Spawn_Button.Checked = false;
            Mage_Grunt_Spawn_Button.Checked = false;
            Ranger_Grunt_Spawn_Button.Checked = false;
            Event_Button.Checked = false;
            Spike_Button.Checked = false;
            Springboard_Button.Checked = false;
            Boss_Button.Checked = false;
        }

        private void Height_Map_Button_Click(object sender, EventArgs e)
        {
            mode = Mode.HEIGHT_MAP_MODE;

            Height_Map_Button.Checked = true;

            Wall_Trigger_Button.Checked = false;
            Switch_Trigger_Button.Checked = false;
            Check_Point_Button.Checked = false;
            Damage_Powerup_Button.Checked = false;
            Speed_Powerup_Button.Checked = false;
            Health_Powerup_Button.Checked = false;
            Crumbling_Platform_Button.Checked = false;
            Paint_Brush_Button.Checked = false;
            Fill_Button.Checked = false;
            Player_Spawn_Button.Checked = false;
            Melee_Grunt_Spawn_Button.Checked = false;
            Mage_Grunt_Spawn_Button.Checked = false;
            Ranger_Grunt_Spawn_Button.Checked = false;
            Event_Button.Checked = false;
            Spike_Button.Checked = false;
            Springboard_Button.Checked = false;
            Boss_Button.Checked = false;
        }

        private void Player_Spawn_Button_Click(object sender, EventArgs e)
        {
            mode = Mode.PLAYER_SPAWN_MODE;

            Player_Spawn_Button.Checked = true;

            Wall_Trigger_Button.Checked = false;
            Switch_Trigger_Button.Checked = false;
            Check_Point_Button.Checked = false;
            Damage_Powerup_Button.Checked = false;
            Speed_Powerup_Button.Checked = false;
            Health_Powerup_Button.Checked = false;
            Crumbling_Platform_Button.Checked = false;
            Height_Map_Button.Checked = false;
            Paint_Brush_Button.Checked = false;
            Fill_Button.Checked = false;
            Melee_Grunt_Spawn_Button.Checked = false;
            Mage_Grunt_Spawn_Button.Checked = false;
            Ranger_Grunt_Spawn_Button.Checked = false;
            Event_Button.Checked = false;
            Spike_Button.Checked = false;
            Springboard_Button.Checked = false;
            Boss_Button.Checked = false;
        }

        private void Melee_Grunt_Spawn_Button_Click(object sender, EventArgs e)
        {
            mode = Mode.MELEE_GRUNT_SPAWN_MODE;

            Melee_Grunt_Spawn_Button.Checked = true;

            Wall_Trigger_Button.Checked = false;
            Switch_Trigger_Button.Checked = false;
            Check_Point_Button.Checked = false;
            Damage_Powerup_Button.Checked = false;
            Speed_Powerup_Button.Checked = false;
            Health_Powerup_Button.Checked = false;
            Crumbling_Platform_Button.Checked = false;
            Height_Map_Button.Checked = false;
            Paint_Brush_Button.Checked = false;
            Fill_Button.Checked = false;
            Player_Spawn_Button.Checked = false;
            Mage_Grunt_Spawn_Button.Checked = false;
            Ranger_Grunt_Spawn_Button.Checked = false;
            Event_Button.Checked = false;
            Spike_Button.Checked = false;
            Springboard_Button.Checked = false;
            Boss_Button.Checked = false;
        }

        private void Mage_Grunt_Spawn_Button_Click(object sender, EventArgs e)
        {
            mode = Mode.MAGE_GRUNT_SPAWN_MODE;

            Mage_Grunt_Spawn_Button.Checked = true;

            Wall_Trigger_Button.Checked = false;
            Switch_Trigger_Button.Checked = false;
            Check_Point_Button.Checked = false;
            Damage_Powerup_Button.Checked = false;
            Speed_Powerup_Button.Checked = false;
            Health_Powerup_Button.Checked = false;
            Crumbling_Platform_Button.Checked = false;
            Height_Map_Button.Checked = false;
            Paint_Brush_Button.Checked = false;
            Fill_Button.Checked = false;
            Player_Spawn_Button.Checked = false;
            Melee_Grunt_Spawn_Button.Checked = false;
            Ranger_Grunt_Spawn_Button.Checked = false;
            Event_Button.Checked = false;
            Spike_Button.Checked = false;
            Springboard_Button.Checked = false;
            Boss_Button.Checked = false;
        }

        private void Ranger_Grunt_Spawn_Button_Click(object sender, EventArgs e)
        {
            mode = Mode.RANGED_GRUNT_SPAWN_MODE;

            Ranger_Grunt_Spawn_Button.Checked = true;

            Wall_Trigger_Button.Checked = false;
            Switch_Trigger_Button.Checked = false;
            Check_Point_Button.Checked = false;
            Damage_Powerup_Button.Checked = false;
            Speed_Powerup_Button.Checked = false;
            Health_Powerup_Button.Checked = false;
            Crumbling_Platform_Button.Checked = false;
            Height_Map_Button.Checked = false;
            Paint_Brush_Button.Checked = false;
            Fill_Button.Checked = false;
            Player_Spawn_Button.Checked = false;
            Melee_Grunt_Spawn_Button.Checked = false;
            Mage_Grunt_Spawn_Button.Checked = false;
            Event_Button.Checked = false;
            Spike_Button.Checked = false;
            Springboard_Button.Checked = false;
            Boss_Button.Checked = false;
        }

        private void Event_Button_Click(object sender, EventArgs e)
        {
            mode = Mode.EVENT_MODE;

            Event_Button.Checked = true;

            Wall_Trigger_Button.Checked = false;
            Switch_Trigger_Button.Checked = false;
            Check_Point_Button.Checked = false;
            Damage_Powerup_Button.Checked = false;
            Speed_Powerup_Button.Checked = false;
            Health_Powerup_Button.Checked = false;
            Crumbling_Platform_Button.Checked = false;
            Height_Map_Button.Checked = false;
            Paint_Brush_Button.Checked = false;
            Fill_Button.Checked = false;
            Player_Spawn_Button.Checked = false;
            Melee_Grunt_Spawn_Button.Checked = false;
            Mage_Grunt_Spawn_Button.Checked = false;
            Ranger_Grunt_Spawn_Button.Checked = false;
            Spike_Button.Checked = false;
            Springboard_Button.Checked = false;
            Boss_Button.Checked = false;
        }
        private void Check_Point_Button_Click(object sender, EventArgs e)
        {
            mode = Mode.CHECK_POINT_MODE;

            Check_Point_Button.Checked = true;

            Wall_Trigger_Button.Checked = false;
            Switch_Trigger_Button.Checked = false;
            Damage_Powerup_Button.Checked = false;
            Speed_Powerup_Button.Checked = false;
            Health_Powerup_Button.Checked = false;
            Crumbling_Platform_Button.Checked = false;
            Ranger_Grunt_Spawn_Button.Checked = false;
            Height_Map_Button.Checked = false;
            Paint_Brush_Button.Checked = false;
            Fill_Button.Checked = false;
            Player_Spawn_Button.Checked = false;
            Melee_Grunt_Spawn_Button.Checked = false;
            Mage_Grunt_Spawn_Button.Checked = false;
            Event_Button.Checked = false;
            Springboard_Button.Checked = false;
            Boss_Button.Checked = false;
        }
        private void Health_Powerup_Button_Click(object sender, EventArgs e)
        {
            mode = Mode.HEALTH_POWERUP_MODE;

            Health_Powerup_Button.Checked = true;

            Wall_Trigger_Button.Checked = false;
            Switch_Trigger_Button.Checked = false;
            Check_Point_Button.Checked = false;
            Damage_Powerup_Button.Checked = false;
            Speed_Powerup_Button.Checked = false;
            Crumbling_Platform_Button.Checked = false;
            Ranger_Grunt_Spawn_Button.Checked = false;
            Height_Map_Button.Checked = false;
            Paint_Brush_Button.Checked = false;
            Fill_Button.Checked = false;
            Player_Spawn_Button.Checked = false;
            Melee_Grunt_Spawn_Button.Checked = false;
            Mage_Grunt_Spawn_Button.Checked = false;
            Event_Button.Checked = false;
            Spike_Button.Checked = false;
            Springboard_Button.Checked = false;
            Boss_Button.Checked = false;
        }

        private void Speed_Powerup_Button_Click(object sender, EventArgs e)
        {
            mode = Mode.SPEED_POWERUP_MODE;

            Speed_Powerup_Button.Checked = true;

            Wall_Trigger_Button.Checked = false;
            Switch_Trigger_Button.Checked = false;
            Check_Point_Button.Checked = false;
            Damage_Powerup_Button.Checked = false;
            Health_Powerup_Button.Checked = false;
            Crumbling_Platform_Button.Checked = false;
            Ranger_Grunt_Spawn_Button.Checked = false;
            Height_Map_Button.Checked = false;
            Paint_Brush_Button.Checked = false;
            Fill_Button.Checked = false;
            Player_Spawn_Button.Checked = false;
            Melee_Grunt_Spawn_Button.Checked = false;
            Mage_Grunt_Spawn_Button.Checked = false;
            Event_Button.Checked = false;
            Spike_Button.Checked = false;
            Springboard_Button.Checked = false;
            Boss_Button.Checked = false;
        }

        private void Damage_Powerup_Button_Click(object sender, EventArgs e)
        {
            mode = Mode.DAMAGE_POWERUP_MODE;

            Damage_Powerup_Button.Checked = true;

            Wall_Trigger_Button.Checked = false;
            Switch_Trigger_Button.Checked = false;
            Check_Point_Button.Checked = false;
            Speed_Powerup_Button.Checked = false;
            Health_Powerup_Button.Checked = false;
            Crumbling_Platform_Button.Checked = false;
            Ranger_Grunt_Spawn_Button.Checked = false;
            Height_Map_Button.Checked = false;
            Paint_Brush_Button.Checked = false;
            Fill_Button.Checked = false;
            Player_Spawn_Button.Checked = false;
            Melee_Grunt_Spawn_Button.Checked = false;
            Mage_Grunt_Spawn_Button.Checked = false;
            Event_Button.Checked = false;
            Spike_Button.Checked = false;
            Springboard_Button.Checked = false;
            Boss_Button.Checked = false;
        }
        private void Crumbling_Platform_Button_Click(object sender, EventArgs e)
        {
            mode = Mode.CRUMBLING_PLATFORM_MODE;

            Crumbling_Platform_Button.Checked = true;

            Wall_Trigger_Button.Checked = false;
            Switch_Trigger_Button.Checked = false;
            Damage_Powerup_Button.Checked = false;
            Check_Point_Button.Checked = false;
            Speed_Powerup_Button.Checked = false;
            Health_Powerup_Button.Checked = false;
            Ranger_Grunt_Spawn_Button.Checked = false;
            Height_Map_Button.Checked = false;
            Paint_Brush_Button.Checked = false;
            Fill_Button.Checked = false;
            Player_Spawn_Button.Checked = false;
            Melee_Grunt_Spawn_Button.Checked = false;
            Mage_Grunt_Spawn_Button.Checked = false;
            Event_Button.Checked = false;
            Spike_Button.Checked = false;
            Springboard_Button.Checked = false;
            Boss_Button.Checked = false;
        }
        private void Switch_Trigger_Button_Click(object sender, EventArgs e)
        {
            mode = Mode.SWITCH_TRIGGER_MODE;

            Switch_Trigger_Button.Checked = true;

            Wall_Trigger_Button.Checked = false;
            Crumbling_Platform_Button.Checked = false;
            Damage_Powerup_Button.Checked = false;
            Check_Point_Button.Checked = false;
            Speed_Powerup_Button.Checked = false;
            Health_Powerup_Button.Checked = false;
            Ranger_Grunt_Spawn_Button.Checked = false;
            Height_Map_Button.Checked = false;
            Paint_Brush_Button.Checked = false;
            Fill_Button.Checked = false;
            Player_Spawn_Button.Checked = false;
            Melee_Grunt_Spawn_Button.Checked = false;
            Mage_Grunt_Spawn_Button.Checked = false;
            Event_Button.Checked = false;
            Spike_Button.Checked = false;
            Springboard_Button.Checked = false;
            Boss_Button.Checked = false;
        }

        private void Wall_Trigger_Button_Click(object sender, EventArgs e)
        {
            mode = Mode.WALL_TRIGGER_MODE;

            Wall_Trigger_Button.Checked = true;

            Switch_Trigger_Button.Checked = false;
            Crumbling_Platform_Button.Checked = false;
            Damage_Powerup_Button.Checked = false;
            Check_Point_Button.Checked = false;
            Speed_Powerup_Button.Checked = false;
            Health_Powerup_Button.Checked = false;
            Ranger_Grunt_Spawn_Button.Checked = false;
            Height_Map_Button.Checked = false;
            Paint_Brush_Button.Checked = false;
            Fill_Button.Checked = false;
            Player_Spawn_Button.Checked = false;
            Melee_Grunt_Spawn_Button.Checked = false;
            Mage_Grunt_Spawn_Button.Checked = false;
            Event_Button.Checked = false;
            Spike_Button.Checked = false;
            Springboard_Button.Checked = false;
            Boss_Button.Checked = false;
        }

        private void Spike_Button_Click(object sender, EventArgs e)
        {
            mode = Mode.SPIKE_MODE;

            Spike_Button.Checked = true;

            Wall_Trigger_Button.Checked = false;
            Switch_Trigger_Button.Checked = false;
            Check_Point_Button.Checked = false;
            Damage_Powerup_Button.Checked = false;
            Speed_Powerup_Button.Checked = false;
            Health_Powerup_Button.Checked = false;
            Crumbling_Platform_Button.Checked = false;
            Paint_Brush_Button.Checked = false;
            Height_Map_Button.Checked = false;
            Player_Spawn_Button.Checked = false;
            Melee_Grunt_Spawn_Button.Checked = false;
            Mage_Grunt_Spawn_Button.Checked = false;
            Ranger_Grunt_Spawn_Button.Checked = false;
            Event_Button.Checked = false;
            Fill_Button.Checked = false;
            Springboard_Button.Checked = false;
            Boss_Button.Checked = false;
        }

        private void Springboard_Button_Click(object sender, EventArgs e)
        {
            mode = Mode.SPRINGBOARD_MODE;

            Springboard_Button.Checked = true;

            Paint_Brush_Button.Checked = false;
            Wall_Trigger_Button.Checked = false;
            Switch_Trigger_Button.Checked = false;
            Check_Point_Button.Checked = false;
            Damage_Powerup_Button.Checked = false;
            Speed_Powerup_Button.Checked = false;
            Health_Powerup_Button.Checked = false;
            Crumbling_Platform_Button.Checked = false;
            Fill_Button.Checked = false;
            Height_Map_Button.Checked = false;
            Player_Spawn_Button.Checked = false;
            Melee_Grunt_Spawn_Button.Checked = false;
            Mage_Grunt_Spawn_Button.Checked = false;
            Ranger_Grunt_Spawn_Button.Checked = false;
            Event_Button.Checked = false;
            Spike_Button.Checked = false;
            Boss_Button.Checked = false;
        }

        private void Boss_Button_Click(object sender, EventArgs e)
        {
            mode = Mode.BOSS_MODE;

            Boss_Button.Checked = true;

            Springboard_Button.Checked = false;
            Paint_Brush_Button.Checked = false;
            Wall_Trigger_Button.Checked = false;
            Switch_Trigger_Button.Checked = false;
            Check_Point_Button.Checked = false;
            Damage_Powerup_Button.Checked = false;
            Speed_Powerup_Button.Checked = false;
            Health_Powerup_Button.Checked = false;
            Crumbling_Platform_Button.Checked = false;
            Fill_Button.Checked = false;
            Height_Map_Button.Checked = false;
            Player_Spawn_Button.Checked = false;
            Melee_Grunt_Spawn_Button.Checked = false;
            Mage_Grunt_Spawn_Button.Checked = false;
            Ranger_Grunt_Spawn_Button.Checked = false;
            Event_Button.Checked = false;
            Spike_Button.Checked = false;
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog save = new SaveFileDialog();

            save.Filter = "XML File|*.xml";
            save.DefaultExt = ".xml";

            if (DialogResult.OK == save.ShowDialog())
            {

                for (int i = 0; i < layers.Count; i++)
                {
                    for (int x = 0; x < levelSize.Width; x++)
                    {
                        for (int y = 0; y < levelSize.Height; y++)
                        {
                            if (layers[i].Level[x, y].HeightMap == null)
                            {
                                layers[i].Level[x, y].HeightMap = new int[tileSize.Width];
                            }
                        }
                    }
                }

                // Layer / Tiles
                XElement xRoot = new XElement("Layers");

                XAttribute xLevelWidth = new XAttribute("LevelWidth", levelSize.Width);
                xRoot.Add(xLevelWidth);

                XAttribute xLevelHeight = new XAttribute("LevelHeight", levelSize.Height);
                xRoot.Add(xLevelHeight);

                XAttribute xTileSetWidth = new XAttribute("TileSetWidth", tileSetSize.Width);
                xRoot.Add(xTileSetWidth);

                XAttribute xTileSetHeight = new XAttribute("TileSetHeight", tileSetSize.Height);
                xRoot.Add(xTileSetHeight);

                XAttribute xTileWidth = new XAttribute("TileWidth", tileSize.Width);
                xRoot.Add(xTileWidth);

                XAttribute xTileHeight = new XAttribute("TileHeight", tileSize.Height);
                xRoot.Add(xTileHeight);

                tileSetFile = Path.GetFileName(tileSetFile);
                XAttribute xTileSetFile = new XAttribute("TileSetFile", tileSetFile);
                xRoot.Add(xTileSetFile);

                for (int i = 0; i < layers.Count(); ++i)
                {
                    XElement xLayer = new XElement("Layer");
                    xRoot.Add(xLayer);

                    XAttribute xLayerName = new XAttribute("LayerName", layers[i].Name);
                    xLayer.Add(xLayerName);

                    XAttribute xLayerVisibility = new XAttribute("LayerVisibility", layers[i].Visible);
                    xLayer.Add(xLayerVisibility);

                    XElement xLevel = new XElement("Level");
                    xLayer.Add(xLevel);

                    for (int x = 0; x < levelSize.Width; ++x)
                    {
                        for (int y = 0; y < levelSize.Height; ++y)
                        {
                            if (layers[i].Level[x, y].X == 0 && layers[i].Level[x, y].Y == 0)
                                continue;

                            XElement xTile = new XElement("Tile");
                            xLevel.Add(xTile);

                            XAttribute xTileMapX = new XAttribute("TileMapCoordX", x);
                            xTile.Add(xTileMapX);

                            XAttribute xTileMapY = new XAttribute("TileMapCoordY", y);
                            xTile.Add(xTileMapY);

                            XAttribute xTileCoordX = new XAttribute("TileSetCoordX", layers[i].Level[x, y].X);
                            xTile.Add(xTileCoordX);

                            XAttribute xTileCoordY = new XAttribute("TileSetCoordY", layers[i].Level[x, y].Y);
                            xTile.Add(xTileCoordY);

                            //XElement xTileHeightmap = new XElement("Heightmap");
                            //xTile.Add(xTileHeightmap);


                            //for (int h = 0; h < tileSize.Width; h++)
                            //{
                            //    XAttribute xHeightmapData = new XAttribute("Height" + h, layers[i].Level[x, y].HeightMap[h]);
                            //    xTileHeightmap.Add(xHeightmapData);
                            //}
                        }
                    }
                }

                XElement xHeightmaps = new XElement("Heightmaps");
                xRoot.Add(xHeightmaps);

                for (int i = 0; i < heightMaps.Count; i++)
                {
                    XElement xHeightmap = new XElement("Heightmap");
                    xHeightmaps.Add(xHeightmap);

                    XAttribute xTileSetCoordX = new XAttribute("TileSetCoordX", heightMaps[i].X);
                    xHeightmap.Add(xTileSetCoordX);

                    XAttribute xTileSetCoordY = new XAttribute("TileSetCoordY", heightMaps[i].Y);
                    xHeightmap.Add(xTileSetCoordY);


                    for (int h = 0; h < tileSize.Width; h++)
                    {
                        XAttribute xHeightmapData = new XAttribute("Height" + h, heightMaps[i].HeightMap[h]);
                        xHeightmap.Add(xHeightmapData);
                    }
                }

                xRoot.Save(save.FileName);

                // Objects

                xRoot = new XElement("Objects");

                for (int x = 0; x < levelSize.Width; ++x)
                {
                    for (int y = 0; y < levelSize.Height; ++y)
                    {
                        XElement xObject = new XElement("Object");
                        XAttribute xObjectX = new XAttribute("X", x);
                        XAttribute xObjectY = new XAttribute("Y", y);
                        XAttribute xObjectType = new XAttribute("Type", Spawns[x, y].ToString());

                        if (Spawns[x, y].ToString() == "NULL")
                            continue;

                        xRoot.Add(xObject);
                        xObject.Add(xObjectX);
                        xObject.Add(xObjectY);
                        xObject.Add(xObjectType);

                        if (Spawns[x, y].ToString() == "EVENT")
                        {
                            XAttribute xObjectEvent = new XAttribute("Event", events[x, y]);
                            xObject.Add(xObjectEvent);
                        }
                    }
                }

                save.FileName = System.IO.Path.ChangeExtension(save.FileName, "ObjXml");
                xRoot.Save(save.FileName);
            }
        }

        private void levelToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog open = new OpenFileDialog();
            open.Filter = "XML Files|*xml";

            if (DialogResult.OK == open.ShowDialog())
            {
                XElement xRoot = XElement.Load(open.FileName);

                XAttribute xLevelWidth = xRoot.Attribute("LevelWidth");

                XAttribute xLevelHeight = xRoot.Attribute("LevelHeight");

                XAttribute xTileSetWidth = xRoot.Attribute("TileSetWidth");

                XAttribute xTileSetHeight = xRoot.Attribute("TileSetHeight");

                XAttribute xTileWidth = xRoot.Attribute("TileWidth");

                XAttribute xTileHeight = xRoot.Attribute("TileHeight");

                XAttribute xTileSetFile = xRoot.Attribute("TileSetFile");

                //-------------

                levelSize.Width = int.Parse(xLevelWidth.Value);
                levelSize.Height = int.Parse(xLevelHeight.Value);
                tileSetSize.Width = int.Parse(xTileSetWidth.Value);
                tileSetSize.Height = int.Parse(xTileSetHeight.Value);
                tileSize.Width = int.Parse(xTileWidth.Value);
                tileSize.Height = int.Parse(xTileHeight.Value);
                tileSetFile = xTileSetFile.Value;
                tileSet = new Bitmap(systemPath + "\\" + tileSetFile);

                IEnumerable<XElement> xLayers = xRoot.Elements("Layer");

                foreach (XElement xLayer in xLayers)
                {
                    XAttribute xLayerName = xLayer.Attribute("LayerName");

                    XAttribute xLayerVisibility = xLayer.Attribute("LayerVisibility");

                    XElement xLevel = xLayer.Element("Level");

                    //-------------

                    Layer l = new Layer();

                    l.Name = xLayerName.Value;
                    l.Visible = bool.Parse(xLayerVisibility.Value);

                    Tile[,] lev = new Tile[levelSize.Width, levelSize.Height];

                    IEnumerable<XElement> xTiles = xLevel.Elements("Tile");

                    int i = 0;

                    foreach (XElement xTile in xTiles)
                    {
                        i++;
                        XAttribute xTileMapCoordX = xTile.Attribute("TileMapCoordX");

                        XAttribute xTileMapCoordY = xTile.Attribute("TileMapCoordY");

                        XAttribute xTileSetCoordX = xTile.Attribute("TileSetCoordX");

                        XAttribute xTileSetCoordY = xTile.Attribute("TileSetCoordY");

                        // XElement xHeightmap = xTile.Element("Heightmap");

                        //-------------

                        lev[int.Parse(xTileMapCoordX.Value), int.Parse(xTileMapCoordY.Value)].X = int.Parse(xTileSetCoordX.Value);
                        lev[int.Parse(xTileMapCoordX.Value), int.Parse(xTileMapCoordY.Value)].Y = int.Parse(xTileSetCoordY.Value);


                        //lev[int.Parse(xTileMapCoordX.Value), int.Parse(xTileMapCoordY.Value)].HeightMap = new int[tileSize.Width];
                        //for (int h = 0; h < tileSize.Width; h++)
                        //{
                        //    lev[int.Parse(xTileMapCoordX.Value), int.Parse(xTileMapCoordY.Value)].HeightMap[h] = int.Parse(xHeightmap.Attribute("Height" + h).Value);
                        //}
                    }

                    layerTool.Close();
                    layerTool = null;

                    toolStripButton8_Click(this, EventArgs.Empty);

                    l.Level = lev;
                    layerTool.ChangeTextBox(l.Name);

                    layers[layerTool.Layers.Count - 1] = l;

                    LevelPanel.Invalidate();
                    TileSetPanel.Invalidate();
                }

                heightMaps = new List<Tile>();

                for (int x = 0; x < tileSetSize.Width; x++)
                {
                    for (int y = 0; y < tileSetSize.Height; y++)
                    {
                        Tile temp = new Tile();
                        temp.X = x;
                        temp.Y = y;

                        temp.HeightMap = new int[tileSize.Width];

                        heightMaps.Add(temp);
                    }
                }

                XElement xHeights = xRoot.Element("Heightmaps");

                IEnumerable<XElement> xHeightmaps = xHeights.Elements("Heightmap");

                int height = 0;
                foreach (XElement xHeightmap in xHeightmaps)
                {
                    XAttribute xTileSetCoordX = xHeightmap.Attribute("TileSetCoordX");

                    XAttribute xTileSetCoordY = xHeightmap.Attribute("TileSetCoordY");

                    Tile heightmapTile = new Tile();
                    heightmapTile.HeightMap = new int[tileSize.Width];

                    heightmapTile.X = int.Parse(xTileSetCoordX.Value);
                    heightmapTile.Y = int.Parse(xTileSetCoordY.Value);

                    for (int h = 0; h < tileSize.Width; h++)
                    {
                        heightmapTile.HeightMap[h] = int.Parse(xHeightmap.Attribute("Height" + h).Value);
                    }

                    heightMaps[height] = heightmapTile;

                    height++;
                }
            }

            for (int i = 0; i < layers.Count; i++)
            {
                for (int x = 0; x < levelSize.Width; x++)
                {
                    for (int y = 0; y < levelSize.Height; y++)
                    {
                        for (int h = 0; h < heightMaps.Count; h++)
                        {
                            if (layers[i].Level[x, y] == heightMaps[h])
                            {
                                layers[i].Level[x, y].HeightMap = heightMaps[h].HeightMap;
                            }
                        }
                    }
                }
            }

            Size size = new Size(levelSize.Width * tileSize.Width, levelSize.Height * tileSize.Height);
            LevelPanel.AutoScrollMinSize = size;

            size = new Size(tileSetSize.Width * tileSize.Width, tileSetSize.Height * tileSize.Height);
            TileSetPanel.AutoScrollMinSize = size;
        }

        private void objectsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog open = new OpenFileDialog();
            open.Filter = "Object XML Files|*ObjXml";

            if (DialogResult.OK == open.ShowDialog())
            {
                XElement xRoot = XElement.Load(open.FileName);

                IEnumerable<XElement> xObjects = xRoot.Elements("Object");

                Spawns = new Objects[levelSize.Width, levelSize.Height];
                events = new string[levelSize.Width, levelSize.Height];

                foreach (XElement xObject in xObjects)
                {
                    XAttribute xType = xObject.Attribute("Type");

                    XAttribute xObjectX = xObject.Attribute("X");

                    XAttribute xObjectY = xObject.Attribute("Y");

                    XAttribute xObjectEvent = xObject.Attribute("Event");

                    if (xType.Value == Objects.NULL.ToString())
                    {
                        Spawns[int.Parse(xObjectX.Value), int.Parse(xObjectY.Value)] = Objects.NULL;
                    }
                    else if (xType.Value == Objects.PLAYER_OBJ.ToString())
                    {
                        Spawns[int.Parse(xObjectX.Value), int.Parse(xObjectY.Value)] = Objects.PLAYER_OBJ;
                    }
                    else if (xType.Value == Objects.RANGED_GRUNT_OBJ.ToString())
                    {
                        Spawns[int.Parse(xObjectX.Value), int.Parse(xObjectY.Value)] = Objects.RANGED_GRUNT_OBJ;
                    }
                    else if (xType.Value == Objects.MAGE_GRUNT_OBJ.ToString())
                    {
                        Spawns[int.Parse(xObjectX.Value), int.Parse(xObjectY.Value)] = Objects.MAGE_GRUNT_OBJ;
                    }
                    else if (xType.Value == Objects.MELEE_GRUNT_OBJ.ToString())
                    {
                        Spawns[int.Parse(xObjectX.Value), int.Parse(xObjectY.Value)] = Objects.MELEE_GRUNT_OBJ;
                    }
                    else if (xType.Value == Objects.EVENT.ToString())
                    {
                        Spawns[int.Parse(xObjectX.Value), int.Parse(xObjectY.Value)] = Objects.EVENT;
                        events[int.Parse(xObjectX.Value), int.Parse(xObjectY.Value)] = xObjectEvent.Value;
                    }
                    else if (xType.Value == Objects.CHECK_POINT_OBJ.ToString())
                    {
                        Spawns[int.Parse(xObjectX.Value), int.Parse(xObjectY.Value)] = Objects.CHECK_POINT_OBJ;
                    }
                    else if (xType.Value == Objects.HEALTH_POWERUP_OBJ.ToString())
                    {
                        Spawns[int.Parse(xObjectX.Value), int.Parse(xObjectY.Value)] = Objects.HEALTH_POWERUP_OBJ;
                    }
                    else if (xType.Value == Objects.SPEED_POWERUP_OBJ.ToString())
                    {
                        Spawns[int.Parse(xObjectX.Value), int.Parse(xObjectY.Value)] = Objects.SPEED_POWERUP_OBJ;
                    }
                    else if (xType.Value == Objects.DAMAGE_POWERUP_OBJ.ToString())
                    {
                        Spawns[int.Parse(xObjectX.Value), int.Parse(xObjectY.Value)] = Objects.DAMAGE_POWERUP_OBJ;
                    }
                    else if (xType.Value == Objects.CRUMBLING_PLATFORM_OBJ.ToString())
                    {
                        Spawns[int.Parse(xObjectX.Value), int.Parse(xObjectY.Value)] = Objects.CRUMBLING_PLATFORM_OBJ;
                    }
                    else if (xType.Value == Objects.SWITCH_TRIGGER_OBJ.ToString())
                    {
                        Spawns[int.Parse(xObjectX.Value), int.Parse(xObjectY.Value)] = Objects.SWITCH_TRIGGER_OBJ;
                    }
                    else if (xType.Value == Objects.WALL_TRIGGER_OBJ.ToString())
                    {
                        Spawns[int.Parse(xObjectX.Value), int.Parse(xObjectY.Value)] = Objects.WALL_TRIGGER_OBJ;
                    }
                    else if (xType.Value == Objects.SPIKE_OBJ.ToString())
                    {
                        Spawns[int.Parse(xObjectX.Value), int.Parse(xObjectY.Value)] = Objects.SPIKE_OBJ;
                    }
                    else if (xType.Value == Objects.SPRINGBOARD_OBJ.ToString())
                    {
                        Spawns[int.Parse(xObjectX.Value), int.Parse(xObjectY.Value)] = Objects.SPRINGBOARD_OBJ;
                    }
                    else if (xType.Value == Objects.BOSS_OBJ.ToString())
                    {
                        Spawns[int.Parse(xObjectX.Value), int.Parse(xObjectY.Value)] = Objects.BOSS_OBJ;
                    }
                }

                LevelPanel.Invalidate();
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form1_FormClosing(sender, new FormClosingEventArgs(CloseReason.ApplicationExitCall, false));
            Dispose(true);
        }

        private void PaintBrush_button_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }

        private void viewGrid_Mouse_Click(object sender, EventArgs e)
        {
            Grid = !Grid;
            LevelPanel.Invalidate();
        }
    }
}